package com.example.springboot.utils;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 枚举工具类
 *
 * <p>
 * @author Zhang.Z
 * @version 2025-09-20
 */
public final class EnumUtils {

    private static final Logger logger = LoggerFactory.getLogger(EnumUtils.class);

    private static final String DEFAULT_ENUM_NAME = "name";

    private EnumUtils() {
    }

    /**
     * 枚举转List格式
     *
     * @param targetEnumClazz 目标枚举Clazz
     * @return 装换结果
     */
    public static List<Map<String, Object>> toMapList(Class targetEnumClazz) {
        return toList(targetEnumClazz, DEFAULT_ENUM_NAME);
    }

    /**
     * 枚举转List格式
     *
     * @param targetEnumClazz 目标枚举Clazz
     * @param enumName        返回JSON中枚举名称对应的Key
     * @return 转换结果
     */
    public static List<Map<String, Object>> toList(Class targetEnumClazz, String enumName) {
        try {
            //获取方法
            Method[] methods = targetEnumClazz.getMethods();
            Field[] fields = targetEnumClazz.getDeclaredFields();
            List<Field> fieldList = new ArrayList<>();
            for (Method method : methods) {
                for (Field field : fields) {
                    if (method.getName().endsWith(toUpperCaseFirstOne(field.getName()))) {
                        fieldList.add(field);
                    }
                }
            }

            List<Map<String, Object>> resultList = new ArrayList<>();
            //获取值
            Enum[] enums = (Enum[]) targetEnumClazz.getEnumConstants();
            for (Enum e : enums) {
                Map<String, Object> eMap = new HashMap<>();
                String enumNameValue = e.name();
                for (Field field : fieldList) {
                    field.setAccessible(true);
                    if (field.getName().equals(enumName)) {
                        enumNameValue = enumNameValue + ";" + field.get(e);
                    } else {
                        eMap.put(field.getName(), field.get(e));
                    }
                }
                if (enumNameValue.startsWith(";")) {
                    enumNameValue = enumNameValue.substring(1);
                }
                eMap.put(enumName, enumNameValue);
                resultList.add(eMap);
            }

            return resultList;
        } catch (RuntimeException | IllegalAccessException e) {
            logger.error("枚举转List格式出错", e);
        }
        return null;
    }

    /**
     * 首字母转大写
     *
     * @param s 需要操作的字符串
     * @return 转换后结果
     */
    private static String toUpperCaseFirstOne(String s) {
        if (Character.isUpperCase(s.charAt(0))) {
            return s;
        } else {
            return Character.toUpperCase(s.charAt(0)) + s.substring(1);
        }
    }

    public static <T extends Enum<?>> List<T> toList(Class<T> clazz) {
        return Arrays.asList(clazz.getEnumConstants());
    }

    public static <T extends Enum<?>> T getEnum(Object name, Class<T> clazz) {
        List<T> list = toList(clazz);
        for (T t : list) {
            if (t.name().equals(name)) {
                return t;
            }
        }
        return null;
    }

    /**
     * 判断枚举字段是否不存在
     *
     * @param targetEnumClazz 目标枚举
     * @param name            需要判断的值名称
     * @return 判断结果
     */
    public static Boolean checkNameNotExist(Class<?> targetEnumClazz, String name) {
        return !checkNameExist(targetEnumClazz, name);
    }

    /**
     * 判断枚举字段是否存在
     *
     * @param targetEnumClazz 目标枚举
     * @param name            需要判断的值名称
     * @return 判断结果
     */
    public static Boolean checkNameExist(Class<?> targetEnumClazz, String name) {
        checkTargetEnumAndEnumName(targetEnumClazz, DEFAULT_ENUM_NAME);
        if (name == null || "".equals(name.trim())) {
            throw new NullPointerException("name is null");
        }

        Object[] objects = targetEnumClazz.getEnumConstants();
        if (objects == null || objects.length < 1) {
            return false;
        }
        @SuppressWarnings("rawtypes")
        Enum[] enums = (Enum[]) objects;
        for (Enum<?> e : enums) {
            if (name.equals(e.name())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 检测目标枚举和枚举返回名称name对应的Key
     *
     * @param targetEnumClazz 目标枚举Clazz
     * @param enumName        枚举返回名称name对应的Key
     */
    private static void checkTargetEnumAndEnumName(Class<?> targetEnumClazz, String enumName) {
        if (targetEnumClazz == null) {
            throw new NullPointerException("targetEnumClazz is null");
        }
        if (!targetEnumClazz.isEnum()) {
            throw new IllegalArgumentException("enum class type error");
        }
        if (enumName == null || "".equals(enumName.trim())) {
            throw new NullPointerException("enumName is null");
        }
    }

}
